package com.whfc.iot.mach.server;

import com.whfc.common.util.JSONUtil;
import com.whfc.hdc.dto.AppDeviceDTO;
import com.whfc.hdc.service.AppDeviceService;
import com.whfc.iot.handler.DefaultServerHandler;
import com.whfc.iot.mach.entity.MachMsg;
import com.whfc.iot.mach.processor.MachUpMsgProcessor;
import com.whfc.iot.mach.processor.MachUpMsgProcessorFactory;
import com.whfc.iot.session.Session;
import com.whfc.iot.session.SessionManager;
import com.whfc.iot.util.LoggingUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Description:
 * @author: xugcheng
 * @version: 1.0
 * @date: 2018/11/29 10:41
 */
@ChannelHandler.Sharable
@Component
public class MachServerHandler extends DefaultServerHandler {

    private Logger logger = LoggerFactory.getLogger(MachServerHandler.class);

    @Autowired
    private MachUpMsgProcessorFactory processorFactory;

    @Autowired
    private SessionManager sessionManager;

    @DubboReference(interfaceClass = AppDeviceService.class, version = "1.0.0")
    private AppDeviceService deviceService;

    public MachServerHandler() {
        super();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.debug("{}", LoggingUtil.format(ctx, "CHANNEL_READ", JSONUtil.toString(msg)));
        try {
            MachMsg reqMsg = (MachMsg) msg;
            Integer deviceType = reqMsg.getDeviceType();
            Integer deviceId = reqMsg.getDeviceId();

            Session session = sessionManager.getSessionByDeviceId(deviceId);
            if (session == null) {
                //身份验证
                AppDeviceDTO device = deviceService.getDeviceById(deviceId);
                if (device == null || !deviceType.equals(device.getType())) {
                    logger.warn("非法设备连接,deviceId:{},deviceType:{}", deviceId, deviceType);
                    ctx.close();
                    return;
                }
                //构建session
                session = sessionManager.createSession(deviceType, deviceId, ctx.channel());
            }
            //当前channel与session中的channel不一致
            else if (!session.getChannel().equals(ctx.channel())) {
                Session oldSession = session;
                oldSession.getChannel().close().addListener(future -> {
                    logger.info("旧连接关闭,deviceId={},isDone={},isSuccess={}", deviceId, future.isDone(), future.isSuccess());
                });
                session = sessionManager.createSession(deviceType, deviceId, ctx.channel());
            }

            //处理消息
            MachUpMsgProcessor processor = processorFactory.getMsgProcessor(reqMsg.getCmd());
            if (processor != null) {
                processor.processMsg(reqMsg);
            }
        } catch (Throwable ex) {
            logger.error("处理消息失败", ex);
        }
    }
}
